#include "double_linked_list.hh"

template <typename T>
DoubleLinkedList<T>::DoubleLinkedList ()
  : begin (0)
  , end (0)
{}

template <typename T>
DoubleLinkedList<T>::~DoubleLinkedList ()
{
  LinkedList<T>* parc = begin;
  LinkedList<T>* pred = 0;

  while (parc)
    {
      pred = parc;
      parc = parc->next;
      delete pred->elt;
      delete pred;
    }
}

template <typename T>
void
DoubleLinkedList<T>::push_front (T elt)
{
  LinkedList<T>* head = new LinkedList<T>;

  head->elt = elt;
  head->prev = 0;
  head->next = begin;
  if (begin)
    begin->prev = head;
  else
    end = head;
  begin = head;
}


template <typename T>
void
DoubleLinkedList<T>::push_back (LinkedList<T>* elt)
{
  if (elt != end)
    {
      LinkedList<T>* prev = elt->prev;
      LinkedList<T>* next = elt->next;

      if (prev)
	prev->next = next;
      else
	next = begin;

      next->prev = prev;

      elt->next = 0;
      elt->prev = end;

      end->next = elt;

      end = elt;
    }
}

template <typename T>
void
DoubleLinkedList<T>::push_back (T elt)
{
  LinkedList<T>* head = new LinkedList<T>;

  head->elt = elt;
  head->next = 0;
  head->prev = end;
  if (end)
    end->next = head;
  else
    begin = head;
  end = head;
}

template <typename T>
void
DoubleLinkedList<T>::erase (T elt)
{
  LinkedList<T>* parc = begin;

  while (parc && parc->elt != elt)
    parc = parc->next;

  if (parc)
    {
      if (parc != begin && parc != end)
	{
	  parc->prev->next = parc->next;
	  parc->next->prev = parc->prev;
	}

      if (parc == begin)
	{
	  begin = parc->next;

	  if (begin)
	    begin->prev = 0;
	}

      if (parc == end)
	{
	  end = parc->prev;

	  if (end)
	    end->next = 0;
	}

      delete parc;
    }
}
